package io.gitee.kotle.android.utils

import androidx.lifecycle.*
import io.gitee.kotle.android.iAnnotation.LiveDataStatus

/**
 * 创建一个对象
 */
fun <T> createStatusLiveData() = MutableLiveData<StatusData<T>>()

/**
 * 创建一个对象
 */
fun <T> createStatusListLiveData() = MutableLiveData<StatusData<MutableList<T>>>()

/**
 * 创建一个中介者对象
 */
fun <T> createStatusMediatorLiveData() = MediatorLiveData<StatusData<T>>()

/**
 * 创建一个中介者对象
 */
fun <T> createStatusListMediatorLiveData() = MediatorLiveData<StatusData<MutableList<T>>>()

/**
 * 与协程绑定
 */
inline fun <T> MutableLiveData<StatusData<T>>.runWithStatus(
    errorBlock: ((Throwable) -> T?) = { null },
    finallyBlock: (() -> Unit) = {},
    block: () -> T
) {
    this.running()
    try {
        success(block.invoke())
    } catch (e: Throwable) {
        printStackTrace { e }
        val result = errorBlock.invoke(e)
        if (result == null) {
            error(e.message)
        } else {
            success(result)
        }
    } finally {
        finallyBlock.invoke()
    }
}

/**
 * 只接受成功回调
 */
inline fun <T> LiveData<StatusData<T>>.doOnSuccess(
    life: LifecycleOwner?,
    crossinline doSuccess: Function1<T, Unit>,
): Observer<StatusData<T>> {
    val observer = Observer<StatusData<T>> {
        val data = it?.data
        if (data != null && it.status == StatusData.Success) {
            doSuccess.invoke(data)
        }
    }
    if (life == null) {
        this.observeForever(observer)
    } else {
        this.observe(life, observer)
    }
    return observer
}

/**
 * 注册观察者
 */
fun <T> LiveData<StatusData<T>>.observeStatusData(
    life: LifecycleOwner?,
    block: StatusDataObserver<T>.() -> Unit
): Observer<StatusData<T>> {
    val call = StatusDataObserver<T>()
    block.invoke(call)
    val observer = Observer<StatusData<T>> {
        when (it?.status) {
            StatusData.Error -> {
                call.onError?.invoke(it)
            }
            StatusData.Running -> {
                call.onRunning?.invoke(it)
            }
            StatusData.Success -> {
                call.onSuccess?.invoke(it)
                val data = it.data
                if (data != null) {
                    call.success?.invoke(data)
                }
            }
            else -> {
                call.onElse?.invoke(it)
            }
        }
    }
    if (life == null) {
        this.observeForever(observer)
    } else {
        this.observe(life, observer)
    }
    return observer
}

/**
 * 带有状态的liveData包装类
 */
class StatusData<T> {
    companion object {
        const val Running = 1
        const val Success = 2
        const val Error = 3
    }

    /**
     * 状态
     */
    @LiveDataStatus
    private var _status: Int = Running

    @LiveDataStatus
    val status: Int
        @LiveDataStatus
        get() = _status

    /**
     * 数据
     */
    private var _data: T? = null
    val data: T?
        get() = _data

    /**
     * code
     */
    private var _code: Int? = null
    val code: Int?
        get() = _code

    /**
     * 消息
     */
    private var _message: String? = null
    val message: String?
        get() = _message

    /**
     * 赋值
     */
    fun setValue(@LiveDataStatus status: Int, data: T?, code: Int?, message: String?) {
        this._status = status
        this._data = data
        this._code = code
        this._message = message
    }

    /**
     *成功
     */
    fun success(data: T?, code: Int? = null, message: String? = null) {
        setValue(Success, data, code ?: _code, message ?: _message)
    }

    /**
     * 运行
     */
    fun running(data: T? = null, code: Int? = null, message: String? = null) {
        setValue(Running, data ?: _data, code ?: _code, message ?: _message)
    }

    /**
     * 错误
     */
    fun error(message: String?, data: T? = null, code: Int? = null) {
        setValue(Error, data ?: _data, code ?: _code, message)
    }
}

class StatusDataObserver<T> {
    internal var onError: Function1<StatusData<T>, Unit>? = null
    internal var onRunning: Function1<StatusData<T>, Unit>? = null
    internal var onSuccess: Function1<StatusData<T>, Unit>? = null
    internal var success: Function1<T, Unit>? = null
    internal var onElse: Function1<StatusData<T>, Unit>? = null
    fun doOnError(call: Function1<StatusData<T>, Unit>) {
        onError = call
    }

    fun doOnRunning(call: Function1<StatusData<T>, Unit>) {
        onRunning = call
    }

    fun doOnSuccess(call: Function1<StatusData<T>, Unit>) {
        onSuccess = call
    }

    fun doOnElse(call: Function1<StatusData<T>?, Unit>) {
        onElse = call
    }

    fun doSuccess(call: Function1<T, Unit>) {
        success = call
    }
}


/**
 * 获取非空值
 */
val <T> LiveData<StatusData<T>>.nonValue: StatusData<T>
    get() = this.value ?: StatusData()

/**
 * 获取data
 */
val <T> LiveData<StatusData<T>>.data: T?
    get() = this.value?.data

/**
 * 获取code
 */
val <T> LiveData<StatusData<T>>.code: Int?
    get() = this.value?.code

/**
 * 获取message
 */
val <T> LiveData<StatusData<T>>.message: String?
    get() = this.value?.message

/**
 * 获取status
 */
val <T> LiveData<StatusData<T>>.status: Int?
    @LiveDataStatus
    get() = this.value?.status

/**
 * 是否是运行状态
 */
val <T> LiveData<StatusData<T>>.isRunning: Boolean
    get() = status == StatusData.Running

/**
 * 是否是成功状态
 */
val <T> LiveData<StatusData<T>>.isSuccess: Boolean
    get() = status == StatusData.Success

/**
 * 是否是错误状态
 */
val <T> LiveData<StatusData<T>>.isError: Boolean
    get() = status == StatusData.Error

/**
 * 安全赋值
 */
fun <T> MutableLiveData<T>.safeSetValue(data: T?) {
    if (isMainThread) {
        value = data
    } else {
        postValue(data)
    }
}


/**
 * 赋值
 */
fun <T> MutableLiveData<StatusData<T>>.setStatusData(
    @LiveDataStatus status: Int, data: T?, code: Int?, message: String?
) {
    val oldValue = nonValue
    oldValue.setValue(status, data, code, message)
    safeSetValue(oldValue)
}

/**
 * 成功状态
 */
fun <T> MutableLiveData<StatusData<T>>.success(
    data: T?,
    code: Int? = null,
    message: String? = null
) {
    val oldValue = nonValue
    oldValue.success(data, code, message)
    safeSetValue(oldValue)
}

/**
 * 失败状态
 */
fun <T> MutableLiveData<StatusData<T>>.error(
    message: String?, data: T? = null, code: Int? = null
) {
    val oldValue = nonValue
    oldValue.error(message, data, code)
    safeSetValue(oldValue)
}

/**
 * 运行状态
 */
fun <T> MutableLiveData<StatusData<T>>.running(
    data: T? = null,
    code: Int? = null,
    message: String? = null
) {
    val oldValue = nonValue
    oldValue.running(data, code, message)
    safeSetValue(oldValue)
}


/**
 *观察数据
 */
fun <T, Data : LiveData<T>> Data.observeData(
    life: LifecycleOwner?,
    isObserver: Boolean = true,
    observer: Observer<T?>,
): Pair<Data, Observer<T?>> {
    if (isObserver) {
        if (life == null) {
            this.observeForever(observer)
        } else {
            this.observe(life, observer)
        }
    }
    return Pair(this, observer)
}

/**
 *观察数据
 */
fun <T, Data : LiveData<T>> Data.createObserveForever(observer: Observer<T?>): Pair<Data, Observer<T?>> {
    return observeData(null, false, observer)
}

/**
 * 注册或者取消注册
 */
fun <T, Data : LiveData<T>> Pair<Data, Observer<T?>>.addObserveForever() {
    first.observeForever(second)
}

/**
 * 注册或者取消注册
 */
fun <T, Data : LiveData<T>> Pair<Data, Observer<T?>>.removeObserve() {
    first.removeObserver(second)
}


